package grpc.rpcclient.client;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * @Author: admin
 * @Description:
 * @Date: 2018/9/28 15:43
 */

public class RpcClient {
    public <T> T getRemoteProxy(Class<?> inter, InetSocketAddress socketAddress) {
        return (T) Proxy.newProxyInstance(inter.getClassLoader(), new Class<?>[]{inter}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null;
                Socket socket = null;
                ObjectOutputStream outputStream = null;
                ObjectInputStream inputStream = null;
                try {
                    // socket 客户端
                    socket = new Socket();
                    // 连接socket服务端
                    socket.connect(socketAddress);
                    // 输出流
                    outputStream = new ObjectOutputStream(socket.getOutputStream());
                    // 输入流
                    inputStream = new ObjectInputStream(socket.getInputStream());
                    // 写入请求接口名
                    outputStream.writeUTF(inter.getName());
                    // 写入请求接口方法名
                    outputStream.writeUTF(method.getName());
                    // 写入请求接口方法参数类型
                    outputStream.writeObject(method.getGenericParameterTypes());
                    // 写入请求接口方法参数
                    outputStream.writeObject(args);
                    //  获取返回值
                    result = inputStream.readObject();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (inputStream != null) inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        if (outputStream != null) {
                            outputStream.flush();
                            outputStream.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        if (socket != null) socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                return result;
            }
        });
    }
}

